package etxt2db.features;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import edu.cmu.minorthird.text.Span;
import etxt2db.api.Document;
import etxt2db.corpus.DocumentBasedTextBase;
import etxt2db.corpus.MinorthirdDocument;
import etxt2db.corpus.MyAnnotation;

/**
 * A feature classifier using UCompare annotation types as features.
 * 
 * @author Gonçalo Simões
 * @author Rui Lageira
 *
 */
public class UCompareAnnotationFeatureClassifier extends CharacterFeatureClassifier {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2729294495748215948L;
	private transient DocumentBasedTextBase annotatedDocument = null;
	private transient Map<String,Map<Integer,List<String>[]>> featureTags = null;
	
	private String key;

	/**
	 * Constructor receiving the key mapping the UCompare type to use
	 * as feature.
	 * 
	 * @param key the key corresponding to the type to use
	 */
	public UCompareAnnotationFeatureClassifier(String key) {
		this.key=key;
	}
	
	@Override
	public List<String> emit(String text) {
		
		if(annotatedDocument == null || !(annotatedDocument.equals(corpus.getTextBase()))){
			featureTags = new HashMap<String,Map<Integer,List<String>[]>>();
			DocumentBasedTextBase cleanCopy = (DocumentBasedTextBase) corpus.getTextBase();
			Iterator<Span> iter = cleanCopy.documentSpanIterator();

			while(iter.hasNext()){
				Span s = iter.next();
				MinorthirdDocument doc = (MinorthirdDocument) cleanCopy.getDocument(s.getDocumentId());
				Document d = doc.getDocument();
				Map<String, Map<etxt2db.tokenizer.Span, MyAnnotation>> annotationsForDoc = d.getAnnotations();
				Map<etxt2db.tokenizer.Span, MyAnnotation> keyAnnotations = annotationsForDoc.get(key);
				
				if(keyAnnotations==null){
					System.err.println("No annotation for type " + key+ "! The behaviour of the component may not be what you expect! Please check your workflow!");
					keyAnnotations = new HashMap<etxt2db.tokenizer.Span, MyAnnotation>();
				}
				
				if(!featureTags.containsKey(d.getId())){
					Map<Integer,List<String>[]> annotationsPerSection = new HashMap<Integer,List<String>[]>();
					for(int i=0; i<d.getNumSections(); i++){
						int startSection = d.getSectionStartingChar(i);
						etxt2db.tokenizer.Span[] tokens = d.getTokens(i);
						etxt2db.tokenizer.Span[] convertedTokens = new etxt2db.tokenizer.Span[tokens.length];
						for(int k=0; k<tokens.length; k++){
							convertedTokens[k]=new etxt2db.tokenizer.Span(startSection+tokens[k].getStart(), startSection+tokens[k].getEnd());
						}

						@SuppressWarnings("unchecked")
						List<String>[] featuresPerToken = new List[convertedTokens.length];
						for(int k=0; k<convertedTokens.length; k++){
							featuresPerToken[k]=new ArrayList<String>();
							for(etxt2db.tokenizer.Span annotationSpan : keyAnnotations.keySet()){
								if(annotationSpan.intersects(convertedTokens[k])){
									List<Object> obj = keyAnnotations.get(annotationSpan).getDistinguisher();
									StringBuffer buf= new StringBuffer();
									for(Object ob : obj){
										buf.append("_" + ob);
									}
									featuresPerToken[k].add("UCompare_" + key + buf.toString());
								}
							}
						}
						annotationsPerSection.put(i, featuresPerToken);
					}
					featureTags.put(d.getId(), annotationsPerSection);
				}
			}
			annotatedDocument = cleanCopy;
		}
		
		String str = span.getDocumentId();
		String[] docAndSection = str.split("-Section");
		String doc = docAndSection[0];
		int section = Integer.parseInt(docAndSection[1]);
		List<String> result = featureTags.get(doc).get(section)[this.span.getLoTextToken()];
				
		return result;
	}

}
